home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Graphics Plus
/
Graphics Plus.iso
/
msdos
/
fractal
/
fdesi313
/
fdes308s
/
fdesmenu.c
< prev
next >
Wrap
Text File
|
1990-01-19
|
14KB
|
452 lines
/*
Routines for menus using mouse
*/
#include <stdio.h>
#include <graphics.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <dir.h>
#include <conio.h>
#include <dos.h>
#include "fdestria.h"
#include "fdesequa.h"
#include "fdesfile.h"
#include "fdesmous.h"
#include "fdesplot.h"
#define CURSOR_RIGHT (77<<8) /* cursor right key */
#define CURSOR_LEFT (75<<8) /* cursor left key */
float area_scaled; /* area scale factor from zooming */
typedef struct {
int selections; /* number of selections */
char *item[16]; /* 16 strings that represent selections */
} popmenu;
#define ITEM_HEIGHT 20 /* Item height in pixels */
#define CHAR_WIDTH 8 /* Item width per character in pixels */
/* ************************************************************************
pop-up menus
************************************************************************ */
/* menu routines */
int popup(int x, int y, popmenu *menu, int foreground, int background)
/* display a pop-up menu and wait for mouse
selection */
{
int i,rcode;
int left,top,right,bottom;
void *scr_save;
mouse_state m;
int maxwidth;
maxwidth = 0;
for (i=0; i<(*menu).selections; i++) {
if (strlen((*menu).item[i]) > maxwidth)
maxwidth = strlen((*menu).item[i]);
}
left = x;
top = y;
right = x + CHAR_WIDTH*maxwidth + 2;
bottom = y + (*menu).selections*ITEM_HEIGHT;
scr_save = malloc(imagesize(left,top,right,bottom));
if (scr_save == NULL)
{
restorecrtmode();
printf("Out of Memory, Sorry.");
exit(0);
}
/* save screen portion */
getimage(left,top,right,bottom,scr_save);
/* display pop-up menu */
setfillstyle(SOLID_FILL,background);
bar(left,top,right,bottom);
setcolor(foreground);
for (i=0; i<(*menu).selections; i++) {
outtextxy(left+2,top+i*ITEM_HEIGHT+6,(*menu).item[i]);
}
/* input selection from mouse */
do {
mouse_click(&m);
rcode = (m.row - top - 2)/ITEM_HEIGHT + 1;
} while ((rcode < 1) || (rcode > (*menu).selections)
|| !((m.col >= left) && (m.col <= right)));
/* restore screen portion */
putimage(left,top,scr_save,COPY_PUT);
free(scr_save);
return(rcode);
}
int mleft[10],mtop[10],mright,mbottom;
void *mscr_save[10];
int mscr_sp = -1;
/*
putmsg
returns next pixel in X direction
*/
int putmsg(int x, int y, char *str, int colorbk, int colorfo) /* display a pop-up message */
{
if (strlen(str) == 0) return(x);
mscr_sp++;
mleft[mscr_sp] = x;
mtop[mscr_sp] = y;
mright = x + strlen(str)*CHAR_WIDTH + 2;
mbottom = y + ITEM_HEIGHT;
mscr_save[mscr_sp] = malloc(imagesize(mleft[mscr_sp],mtop[mscr_sp],
mright,mbottom));
if (mscr_save[mscr_sp] == NULL)
{
restorecrtmode();
printf("Out of Memory, Sorry.");
exit(0);
}
/* save screen portion */
getimage(mleft[mscr_sp],mtop[mscr_sp],mright,mbottom,mscr_save[mscr_sp]);
/* display pop-up menu */
setfillstyle(SOLID_FILL,colorbk);
bar(mleft[mscr_sp],mtop[mscr_sp],mright,mbottom);
setcolor(colorfo);
outtextxy(mleft[mscr_sp]+2,mtop[mscr_sp]+6,str);
return(mright+1);
}
void clrmsg(void)
{
/* restore screen portion */
if (mscr_sp < 0) {
restorecrtmode();
printf("Too many pops of message text");
exit(0);
}
putimage(mleft[mscr_sp],mtop[mscr_sp],mscr_save[mscr_sp],COPY_PUT);
free(mscr_save[mscr_sp--]);
}
/*
putmsg destructive
*/
int putmsg_d(int x, int y, char *str, int colorbk, int colorfo) /* display a pop-up message */
{
int mleft,mright,mtop,mbottom;
if (strlen(str) == 0) return(x);
mleft = x;
mtop = y;
mright = x + strlen(str)*CHAR_WIDTH + 2;
mbottom = y + ITEM_HEIGHT;
/* display pop-up menu */
setfillstyle(SOLID_FILL,colorbk);
bar(mleft,mtop,mright,mbottom);
setcolor(colorfo);
outtextxy(mleft+2,mtop+6,str);
return(mright+1);
}
/* ************************************************************************
A 'scanf' for graphics mode
returns # of arguments
************************************************************************ */
int gscanf(int x, int y, char *prompt, int maxlength, char *format, ...)
{
char buf[133];
int si; /* string index into buf */
va_list parmlist;
unsigned int ch;
int input_x;
int i;
int rcode;
int mleft, mtop, mright, mbottom;
input_x = putmsg(x,y,prompt,YELLOW,RED);
for (i=0; i<maxlength; i++) buf[i]='_';
buf[maxlength] = 0;
putmsg(input_x, y, buf, WHITE, BLUE);
buf[0] = 0; /* null the string */
si = 0;
do {
if ((ch = getch()) == 0) ch = getch() << 8;
if (ch == 015) break; /* carriage return */
if (ch == 033) /* escape */
{
clrmsg();
clrmsg();
return(0);
}
switch (ch)
{
case 010: /* backspace */
if (si == 0) break;
si--;
buf[si] = 0;
break;
default:
if (si == maxlength) break;
buf[si++] = ch;
buf[si] = 0;
break;
}
mleft = input_x;
mtop = y;
mright = input_x + maxlength*CHAR_WIDTH + 2;
mbottom = y + ITEM_HEIGHT;
setfillstyle(SOLID_FILL,WHITE);
bar(mleft,mtop,mright,mbottom);
setcolor(BLUE);
outtextxy(mleft+2,mtop+6,buf);
} while (1);
if (strlen(buf) != 0)
{
va_start(parmlist,format);
rcode = vsscanf(buf,format,parmlist);
va_end(parmlist);
}
else rcode = 0;
clrmsg();
clrmsg();
return(rcode);
}
/***************************************************************************
Returns filename pointed to by mouse
****************************************************************************/
int fname_cmp(char *s1,char *s2)
{
return(strcmp(s1,s2));
}
char trn_select[15];
char *trn_directory(void) /* returns NULL if no files */
{
struct ffblk ffblock;
int num_files,i;
mouse_state m;
char trn_files[240][9];
char fname[15];
cleardevice();
if (findfirst("*.TRN",&ffblock,0) == -1)
{
putmsg(100,100,"No .TRN files in directory",BLUE,WHITE);
mouse_click(&m);
clrmsg();
return(NULL);
}
else {
num_files = 0;
/* get directory from DOS */
do {
strncpy(fname,ffblock.ff_name,14);
stpcpy(trn_files[num_files],strtok(fname,". "));
num_files++;
} while ((findnext(&ffblock) == 0) && (num_files < 240));
qsort(trn_files[0],num_files,9,fname_cmp);
/* display on screen */
cleardevice();
setcolor(LIGHTGREEN);
for (i=0; i<num_files; i++)
{
outtextxy((i/30)*80,(i%30)*10,trn_files[i]);
}
/* input mouse pointer */
putmsg(0,330,"Click Left to view, Right to End",RED,WHITE);
plot_type = 1; /* do a small plot while inputting */
mouse_idle_job = doIFSrand; /* do a small plot while inputting */
do {
mouse_click(&m);
if (m.buttons & MOUSE_LEFT)
{
i = (m.row/10)%30 + (m.col/80)*30;
if (i>(num_files-1))
{
putmsg(100,100,"click on filename",WHITE,RED);
delay(1000);
clrmsg();
}
else
{
stpcpy(trn_select,trn_files[i]);
/* load in the file */
if (trnfile_load(trn_select) != 0) {
IFS_changed = 1;
}
}
}
} while (!(m.buttons & MOUSE_RIGHT));
clrmsg();
mouse_idle_job = mouse_idle;
return(trn_select);
}
;
}
/*****************************************************************************
Non-destructive line drawing
******************************************************************************/
void *line_stack[10];
int left[10],top[10];
int lsp = -1;
void line_ovly(int x1,int y1,int x2,int y2)
{
int right,bottom;
lsp++;
if (x1 <= x2)
{
left[lsp] = max(0,x1 - 2);
right = min(x2 + 2,maxx);
}
else
{
left[lsp] = max(0,x2 - 2);
right = min(x1 + 2,maxx);
}
if (y1 <= y2)
{
top[lsp] = max(0,y1 - 2);
bottom = min(y2 + 2,maxy);
}
else
{
top[lsp] = max(0,y2 - 2);
bottom = min(y1 + 2,maxy);
}
line_stack[lsp] = malloc(imagesize(left[lsp],top[lsp],right,bottom));
getimage(left[lsp],top[lsp],right,bottom,line_stack[lsp]);
setcolor(WHITE);
line(x1,y1,x2,y2);
}
void line_clear(void)
{
putimage(left[lsp],top[lsp],line_stack[lsp],COPY_PUT);
free(line_stack[lsp]);
lsp--;
}
/******************************************************************************
Mouse input of a zoom box
******************************************************************************/
void box_new(int *x1, int *y1, int *x2, int *y2)
{
mouse_state m;
float widthx,widthy;
float centerx,centery;
int oldcol,oldrow;
float oldwidthx,oldwidthy;
float oldcenterx,oldcentery;
widthx = 300.0;
widthy = widthx*3.0/4.0;
centerx = maxx/2.0;
centery = maxy/2.0;
m.row = maxy/2.0;
m.col = maxx/2.0;
mouse_put(&m);
*x1 = centerx - widthx/2.0;
*x2 = centerx + widthx/2.0;
*y1 = centery - widthy/2.0;
*y2 = centery + widthy/2.0;
while (mouse_get(&m) != 0x00) ;
putmsg(10,10,"Press any key to accept",YELLOW,BLACK);
setlinestyle(DASHED_LINE,0,NORM_WIDTH);
line_ovly(*x1,*y1,*x1,*y2);
line_ovly(*x2,*y1,*x2,*y2);
line_ovly(*x1,*y1,*x2,*y1);
line_ovly(*x1,*y2,*x2,*y2);
oldrow = m.row;
oldcol = m.col;
do
{
mouse_get(&m);
oldwidthx = widthx;
oldwidthy = widthy;
oldcenterx = centerx;
oldcentery = centery;
if ((m.col != oldcol) || (m.row != oldrow))
{
if (m.buttons&MOUSE_LEFT)
{
widthx *= (1.0 + (m.row-oldrow)/100.0);
if (widthx < 20.0) widthx = 20.0;
widthy = widthx*3.0/4.0;
}
else
{
centerx += (m.col-oldcol);
centery += (m.row-oldrow);
}
m.row = maxy/2.0;
m.col = maxx/2.0;
mouse_put(&m);
*x1 = centerx - widthx/2.0;
*x2 = centerx + widthx/2.0;
*y1 = centery - widthy/2.0;
*y2 = centery + widthy/2.0;
if ((*x1 <= 2.0) || (*x2 >maxx-2.0) || (*y1 <= 2.0)
|| (*y2 >= (maxy-2.0)))
{
widthx = oldwidthx;
widthy = oldwidthy;
centerx = oldcenterx;
centery = oldcentery;
*x1 = centerx - widthx/2.0;
*x2 = centerx + widthx/2.0;
*y1 = centery - widthy/2.0;
*y2 = centery + widthy/2.0;
}
line_clear();
line_clear();
line_clear();
line_clear();
line_ovly(*x1,*y1,*x1,*y2);
line_ovly(*x2,*y1,*x2,*y2);
line_ovly(*x1,*y1,*x2,*y1);
line_ovly(*x1,*y2,*x2,*y2);
oldcol = m.col;
oldrow = m.row;
}
} while (!kbhit());
if (getch() == 0) getch();
line_clear();
line_clear();
line_clear();
line_clear();
clrmsg();
}
/******************************************************************************
Zooming on plot
This code really belongs somewhere else.
******************************************************************************/
void zoom_in(void)
{
int x1,y1,x2,y2;
float xscale,xoffset,yscale,yoffset;
putmsg(0,0,"Zoom Box",BLUE,WHITE);
box_new(&x1,&y1,&x2,&y2);
clrmsg();
if (x1 == x2) return;
if (y1 == y2) return;
xscale = maxx/(x2-x1);
yscale = maxy/(y2-y1);
if (xscale > yscale) xscale = yscale;
else yscale = xscale;
xoffset = -((x1+x2)/2.0)*xscale + maxx/2.0;
yoffset = -((y1+y2)/2.0)*yscale + maxy/2.0;
/* scale relative to already scaled triangles */
IFS_rescale(xscale,xoffset,yscale,yoffset,1);
area_scaled *= xscale;
area_scaled *= yscale;
}
void zoom_out(void)
{
area_scaled = 1.0;
IFS_changed = 1;
cleardevice();
doIFSrand();
}